/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.func.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthDataVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthScopeVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldStateVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictCanCelAuthScopeVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictionaryAuthVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictionaryVo;
import com.je.common.base.func.funcPerm.roleSqlAuth.RoleSqlAuthScopeVo;
import com.je.common.base.func.funcPerm.roleSqlAuth.RoleSqlAuthVo;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.*;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.funcperm.FuncPermCache;
import com.je.meta.constant.FuncDataPermCons;
import com.je.meta.model.dd.DictionaryItemVo;
import com.je.meta.rpc.dictionary.DictionaryRpcService;
import com.je.meta.rpc.func.MetaFuncPermService;
import com.je.meta.service.func.FuncPermService;
import com.je.rbac.rpc.RoleRpcService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FuncPermServiceImpl implements FuncPermService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private DictionaryRpcService dictionaryRpcService;
    @Autowired
    private RoleRpcService roleRpcService;
    @Autowired
    private MetaFuncPermService metaFuncPermService;
    @Autowired
    private FuncPermCache funcPermCache;
    @Autowired
    private BeanService beanService;

    @Override
    @Transactional
    public DynaBean doUpdatePerm(DynaBean dynaBean) {
        /**
         * 暂不考虑租户
         */
        String type = dynaBean.getStr("type");
        String funcId = dynaBean.getStr("FUNCPERM_FUNCINFO_ID");
        String funcCode = dynaBean.getStr("FUNCPERM_FUNCINFO_CODE");
        String funcpermType = dynaBean.getStr("FUNCPERM_TYPE");
        String coverValue = dynaBean.getStr("FUNCPERM_COVER_VALUE");
        DynaBean funcPerm = metaService.selectOne("JE_CORE_FUNCPERM",
                ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_ID", funcId).eq("FUNCPERM_TYPE", funcpermType));

        if (funcPerm == null) {

            if (FuncDataPermCons.FIELD_AUTH.equals(funcpermType)) {
                checkData(dynaBean.getStr("FUNCPERM_CONFIG"));
            }
            String id = JEUUID.uuid();
            dynaBean.setStr("JE_CORE_FUNCPERM_ID", id);
            commonService.buildModelCreateInfo(dynaBean);
            String FUNCPERM_CONFIG = dynaBean.getStr("FUNCPERM_CONFIG");
            if ("dictionaryAuth".equals(funcpermType) || "roleSqlAuth".equals(funcpermType) || "fieldAuth".equals(funcpermType)) {
                dynaBean.setStr("FUNCPERM_CONFIG", "");
            }
            metaService.insert(dynaBean);
            saveOrUpdateChildTable(FUNCPERM_CONFIG, id, funcpermType);
        } else {
            dynaBean.setStr("JE_CORE_FUNCPERM_ID", funcPerm.getStr("JE_CORE_FUNCPERM_ID"));
            if ("dictionaryAuth".equals(funcpermType) || "roleSqlAuth".equals(funcpermType) || "fieldAuth".equals(funcpermType)) {
                saveOrUpdateChildTable(dynaBean.getStr("FUNCPERM_CONFIG"), funcPerm.getStr("JE_CORE_FUNCPERM_ID"), funcpermType);
                dynaBean.setStr("FUNCPERM_CONFIG", "");
            }
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }

        metaService.executeSql("UPDATE JE_CORE_FUNCPERM SET FUNCPERM_COVER_VALUE={0} WHERE FUNCPERM_FUNCINFO_ID={1}", coverValue, funcId);
        dynaBean.setStr("FUNCPERM_COVER_VALUE", coverValue);

        //存入缓存
        metaFuncPermService.putRedisCache(funcCode, funcpermType);
        return dynaBean;
    }

    private void checkData(String funcpermConfig) {
        FieldAuthVo fieldAuthVo = JSON.parseObject(funcpermConfig, FieldAuthVo.class);
        FieldAuthScopeVo fieldAuthDeptVo = fieldAuthVo.getDeptAuthFieldVo();
        FieldAuthScopeVo roleAuthFieldVo = fieldAuthVo.getRoleAuthFieldVo();
        FieldAuthScopeVo orgAuthFieldVo = fieldAuthVo.getOrgAuthFieldVo();
        if ((fieldAuthDeptVo.getDatas() == null || fieldAuthDeptVo.getDatas().size() == 0)
                && (roleAuthFieldVo.getDatas() == null || roleAuthFieldVo.getDatas().size() == 0)
                && (orgAuthFieldVo.getDatas() == null || orgAuthFieldVo.getDatas().size() == 0)) {
            throw new PlatformException(MessageUtils.getMessage("function.dataPerm.field.configIsEmpty"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
        }
    }

    private void saveOrUpdateChildTable(String funcpermConfig, String parentId, String funcpermType) {
        if ("dictionaryAuth".equals(funcpermType)) {
            DictionaryAuthVo dictionaryAuthVo = JSON.parseObject(funcpermConfig, DictionaryAuthVo.class);
            List<DictCanCelAuthScopeVo> deptList = dictionaryAuthVo.getDictCanCelAuthDeptList();
            if (deptList != null && deptList.size() > 0) {
                for (DictCanCelAuthScopeVo dept : deptList) {
                    saveDictionaryhildData(dept, funcpermType, parentId, "dept");
                }
            }

            List<DictCanCelAuthScopeVo> orgList = dictionaryAuthVo.getDictCanCelAuthOrgList();
            if (orgList != null && orgList.size() > 0) {
                for (DictCanCelAuthScopeVo org : orgList) {
                    saveDictionaryhildData(org, funcpermType, parentId, "org");
                }
            }
            List<DictCanCelAuthScopeVo> roleList = dictionaryAuthVo.getDictCanCelAuthRoleList();
            if (roleList != null && roleList.size() > 0) {
                for (DictCanCelAuthScopeVo role : roleList) {
                    saveDictionaryhildData(role, funcpermType, parentId, "role");
                }
            }

        }

        if ("roleSqlAuth".equals(funcpermType)) {
            RoleSqlAuthVo roleSqlAuthVo = JSON.parseObject(funcpermConfig, RoleSqlAuthVo.class);
            List<RoleSqlAuthScopeVo> deptList = roleSqlAuthVo.getRoleSqlAuthDeptList();
            if (deptList != null && deptList.size() > 0) {
                for (RoleSqlAuthScopeVo dept : deptList) {
                    saveRoleSqlChildData(dept, funcpermType, parentId, "dept");
                }
            }

            List<RoleSqlAuthScopeVo> orgList = roleSqlAuthVo.getRoleSqlAuthOrgList();
            if (orgList != null && orgList.size() > 0) {
                for (RoleSqlAuthScopeVo org : orgList) {
                    saveRoleSqlChildData(org, funcpermType, parentId, "org");
                }
            }
            List<RoleSqlAuthScopeVo> roleList = roleSqlAuthVo.getRoleSqlAuthRoleList();
            if (roleList != null && roleList.size() > 0) {
                for (RoleSqlAuthScopeVo role : roleList) {
                    saveRoleSqlChildData(role, funcpermType, parentId, "role");
                }
            }

        }

        if ("fieldAuth".equals(funcpermType)) {
            FieldAuthVo fieldAuthVo = JSON.parseObject(funcpermConfig, FieldAuthVo.class);
            FieldAuthScopeVo fieldAuthDeptVo = fieldAuthVo.getDeptAuthFieldVo();
            if (fieldAuthDeptVo != null && fieldAuthDeptVo.getDatas() != null) {
                for (FieldAuthDataVo fieldAuthDataVo : fieldAuthDeptVo.getDatas()) {
                    saveFieldAuthChildData(fieldAuthDataVo, funcpermType, parentId, "dept", fieldAuthDeptVo.getControlScope(), fieldAuthDeptVo.getSelectControl());
                }
            } else {
                saveFieldAuthChildData(null, funcpermType, parentId, "dept", fieldAuthDeptVo.getControlScope(), fieldAuthDeptVo.getSelectControl());
            }
            FieldAuthScopeVo fieldAuthOrgVo = fieldAuthVo.getOrgAuthFieldVo();
            if (fieldAuthOrgVo != null && fieldAuthOrgVo.getDatas() != null) {
                for (FieldAuthDataVo fieldAuthDataVo : fieldAuthOrgVo.getDatas()) {
                    saveFieldAuthChildData(fieldAuthDataVo, funcpermType, parentId, "org", fieldAuthOrgVo.getControlScope(), fieldAuthOrgVo.getSelectControl());
                }
            } else {
                saveFieldAuthChildData(null, funcpermType, parentId, "org", fieldAuthOrgVo.getControlScope(), fieldAuthOrgVo.getSelectControl());
            }
            FieldAuthScopeVo fieldAuthRoleVo = fieldAuthVo.getRoleAuthFieldVo();
            if (fieldAuthRoleVo != null && fieldAuthRoleVo.getDatas() != null) {
                for (FieldAuthDataVo fieldAuthDataVo : fieldAuthRoleVo.getDatas()) {
                    saveFieldAuthChildData(fieldAuthDataVo, funcpermType, parentId, "role", fieldAuthRoleVo.getControlScope(), fieldAuthRoleVo.getSelectControl());
                }
            } else {
                saveFieldAuthChildData(null, funcpermType, parentId, "role", fieldAuthRoleVo.getControlScope(), fieldAuthRoleVo.getSelectControl());
            }
        }

    }

    private void saveFieldAuthChildData(FieldAuthDataVo fieldAuthDataVo, String funcpermType, String parentId, String dataType, String controlScope, String selectScope) {
        DynaBean dynaBean = new DynaBean("JE_CORE_FUNCPERM_CONFIG", true);
        if (fieldAuthDataVo == null) {
            if (StringUtil.isNotEmpty(controlScope) || StringUtil.isNotEmpty(selectScope)) {
                if (StringUtil.isNotEmpty(controlScope)) {
                    dynaBean.setStr("CONFIG_CONTROL_SCOPE", controlScope);
                }
                if (StringUtil.isNotEmpty(selectScope)) {
                    dynaBean.setStr("CONFIG_SELECT_SCOPE", selectScope);
                }
                metaService.update(dynaBean, ConditionsWrapper.builder()
                        .eq("CONFIG_FUNCPERM_ID", parentId)
                        .eq("CONFIG_PERM_TYPE", funcpermType)
                        .eq("CONFIG_TYPE", dataType));
            }

        } else {
            DynaBean config = metaService.selectOne("JE_CORE_FUNCPERM_CONFIG", ConditionsWrapper.builder()
                    .eq("CONFIG_DATA_ID", fieldAuthDataVo.getId())
                    .eq("CONFIG_PERM_TYPE", funcpermType)
                    .eq("CONFIG_FUNCPERM_ID", parentId));
            if (config == null) {
                dynaBean.setStr("CONFIG_FUNCPERM_ID", parentId);
                dynaBean.setStr("CONFIG_TYPE", dataType);
                dynaBean.set("CONFIG_INFO", JSON.toJSONString(fieldAuthDataVo));
                dynaBean.setStr("CONFIG_PERM_TYPE", funcpermType);
                dynaBean.setStr("CONFIG_DATA_ID", fieldAuthDataVo.getId());
                dynaBean.setStr("CONFIG_CONTROL_SCOPE", controlScope);
                dynaBean.setStr("CONFIG_SELECT_SCOPE", selectScope);
                commonService.buildModelCreateInfo(dynaBean);
                metaService.insert(dynaBean);
            } else {
                //如果全部为未勾选，则删除
                if (!checkFieldAuthData(fieldAuthDataVo)) {
                    //删除该行数据
                    metaService.delete("JE_CORE_FUNCPERM_CONFIG", ConditionsWrapper.builder().eq("JE_CORE_FUNCPERM_CONFIG_ID", config.getStr("JE_CORE_FUNCPERM_CONFIG_ID")));
                } else {
                    dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID", config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
                    dynaBean.set("CONFIG_INFO", JSON.toJSONString(fieldAuthDataVo));
                    dynaBean.setStr("CONFIG_CONTROL_SCOPE", controlScope);
                    dynaBean.setStr("CONFIG_SELECT_SCOPE", selectScope);
                    commonService.buildModelModifyInfo(dynaBean);
                    metaService.update(dynaBean);
                }
            }
        }
    }

    private boolean checkFieldAuthData(FieldAuthDataVo fieldAuthDataVo) {
        for (FieldStateVo fieldStateVo : fieldAuthDataVo.getAllFields()) {
            String value = fieldStateVo.getValue();
            if ("1".equals(value)) {
                return true;
            }
        }
        return false;
    }

    private void saveRoleSqlChildData(RoleSqlAuthScopeVo roleSqlAuthScopeVo, String funcpermType, String parentId, String dataType) {
        DynaBean dynaBean = new DynaBean("JE_CORE_FUNCPERM_CONFIG", true);
        DynaBean config = metaService.selectOne("JE_CORE_FUNCPERM_CONFIG", ConditionsWrapper.builder()
                .eq("CONFIG_DATA_ID", roleSqlAuthScopeVo.getId())
                .eq("CONFIG_PERM_TYPE", funcpermType)
                .eq("CONFIG_FUNCPERM_ID", parentId));
        if (config == null) {
            dynaBean.setStr("CONFIG_FUNCPERM_ID", parentId);
            dynaBean.setStr("CONFIG_TYPE", dataType);
            dynaBean.set("CONFIG_INFO", JSON.toJSONString(roleSqlAuthScopeVo));
            dynaBean.setStr("CONFIG_DATA_ID", roleSqlAuthScopeVo.getId());
            dynaBean.setStr("CONFIG_PERM_TYPE", funcpermType);
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
        } else {
            dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID", config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
            dynaBean.set("CONFIG_INFO", JSON.toJSONString(roleSqlAuthScopeVo));
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }
    }

    private void saveDictionaryhildData(DictCanCelAuthScopeVo dictCanCelAuthScopeVo, String funcpermType, String parentId, String dataType) {
        DynaBean dynaBean = new DynaBean("JE_CORE_FUNCPERM_CONFIG", true);
        DynaBean config = metaService.selectOne("JE_CORE_FUNCPERM_CONFIG", ConditionsWrapper.builder()
                .eq("CONFIG_DATA_ID", dictCanCelAuthScopeVo.getId())
                .eq("CONFIG_FUNCPERM_ID", parentId)
                .eq("CONFIG_PERM_TYPE", funcpermType));
        if (config == null) {
            dynaBean.setStr("CONFIG_FUNCPERM_ID", parentId);
            dynaBean.setStr("CONFIG_TYPE", dataType);
            dynaBean.set("CONFIG_INFO", JSON.toJSONString(dictCanCelAuthScopeVo.getDictList()));
            dynaBean.setStr("CONFIG_DATA_ID", dictCanCelAuthScopeVo.getId());
            dynaBean.setStr("CONFIG_PERM_TYPE", funcpermType);
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
        } else {
            dynaBean.setStr("JE_CORE_FUNCPERM_CONFIG_ID", config.getStr("JE_CORE_FUNCPERM_CONFIG_ID"));
            dynaBean.set("CONFIG_INFO", JSON.toJSONString(dictCanCelAuthScopeVo.getDictList()));
            commonService.buildModelModifyInfo(dynaBean);
            metaService.update(dynaBean);
        }
    }


    @Override
    public List<DynaBean> getPermData(DynaBean dynaBean) {
        String FUNCPERM_TYPE = dynaBean.getStr("FUNCPERM_TYPE");
        String type = dynaBean.getStr("type");
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder();
        conditionsWrapper.eq("FUNCPERM_FUNCINFO_ID", dynaBean.getStr("FUNCPERM_FUNCINFO_ID"));
        if (StringUtils.isNotEmpty(FUNCPERM_TYPE)) {
            conditionsWrapper.eq("FUNCPERM_TYPE", dynaBean.getStr("FUNCPERM_TYPE"));
        }
        //如果是租户则增加租户条件
        if ("ZH".equals(type)) {
            conditionsWrapper.eq("SY_TENANT_ID", SecurityUserHolder.getCurrentAccountTenantId());
        }
        List<DynaBean> authList = metaService.select("JE_CORE_FUNCPERM", conditionsWrapper);
        if (authList != null && authList.size() > 0) {
            for (DynaBean authItem : authList) {
                String itemType = authItem.getStr("FUNCPERM_TYPE");
                if ("dictionaryAuth".equals(itemType) || "roleSqlAuth".equals(itemType) || "fieldAuth".equals(itemType)) {
                    String JE_CORE_FUNCPERM_ID = authItem.getStr("JE_CORE_FUNCPERM_ID");
                    List<DynaBean> dataList = metaService.select("JE_CORE_FUNCPERM_CONFIG", ConditionsWrapper.builder().eq("CONFIG_FUNCPERM_ID", JE_CORE_FUNCPERM_ID));
                    //字典授权
                    DictionaryAuthVo dictionaryAuthVo = new DictionaryAuthVo();
                    List<DictCanCelAuthScopeVo> deptDict = new ArrayList();
                    dictionaryAuthVo.setDictCanCelAuthDeptList(deptDict);
                    List<DictCanCelAuthScopeVo> orgDict = new ArrayList();
                    dictionaryAuthVo.setDictCanCelAuthOrgList(orgDict);
                    List<DictCanCelAuthScopeVo> roleDict = new ArrayList();
                    dictionaryAuthVo.setDictCanCelAuthRoleList(roleDict);
                    //角色sql授权
                    RoleSqlAuthVo roleSqlAuthVo = new RoleSqlAuthVo();
                    List<RoleSqlAuthScopeVo> deptRoleSql = new ArrayList<>();
                    roleSqlAuthVo.setRoleSqlAuthDeptList(deptRoleSql);
                    List<RoleSqlAuthScopeVo> orgRoleSql = new ArrayList<>();
                    roleSqlAuthVo.setRoleSqlAuthOrgList(orgRoleSql);
                    List<RoleSqlAuthScopeVo> roleRoleSql = new ArrayList<>();
                    roleSqlAuthVo.setRoleSqlAuthRoleList(roleRoleSql);
                    //字段授权
                    FieldAuthVo fieldAuthVo = new FieldAuthVo();
                    FieldAuthScopeVo roleAuthFieldVo = new FieldAuthScopeVo();
                    List<FieldAuthDataVo> roleDatas = new ArrayList<>();
                    roleAuthFieldVo.setDatas(roleDatas);
                    fieldAuthVo.setRoleAuthFieldVo(roleAuthFieldVo);
                    FieldAuthScopeVo deptAuthFieldVo = new FieldAuthScopeVo();
                    List<FieldAuthDataVo> deptDatas = new ArrayList<>();
                    deptAuthFieldVo.setDatas(deptDatas);
                    fieldAuthVo.setDeptAuthFieldVo(deptAuthFieldVo);
                    FieldAuthScopeVo orgAuthFieldVo = new FieldAuthScopeVo();
                    List<FieldAuthDataVo> orgDatas = new ArrayList<>();
                    orgAuthFieldVo.setDatas(orgDatas);
                    fieldAuthVo.setOrgAuthFieldVo(orgAuthFieldVo);
                    for (DynaBean data : dataList) {
                        String dataType = data.getStr("CONFIG_TYPE");
                        String dataId = data.getStr("CONFIG_DATA_ID");
                        String configInfo = data.getStr("CONFIG_INFO");
                        String CONFIG_CONTROL_SCOPE = data.getStr("CONFIG_CONTROL_SCOPE");
                        String CONFIG_SELECT_SCOPE = data.getStr("CONFIG_SELECT_SCOPE");
                        if ("fieldAuth".equals(itemType)) {
                            if ("org".equals(dataType)) {
                                FieldAuthDataVo fieldAuthDataVo = JSON.parseObject(configInfo, FieldAuthDataVo.class);
                                orgDatas.add(fieldAuthDataVo);
                                orgAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                                orgAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                            }
                            if ("dept".equals(dataType)) {
                                FieldAuthDataVo fieldAuthDataVo = JSON.parseObject(configInfo, FieldAuthDataVo.class);
                                deptDatas.add(fieldAuthDataVo);
                                deptAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                                deptAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                            }
                            if ("role".equals(dataType)) {
                                FieldAuthDataVo fieldAuthDataVo = JSON.parseObject(configInfo, FieldAuthDataVo.class);
                                roleDatas.add(fieldAuthDataVo);
                                roleAuthFieldVo.setSelectControl(CONFIG_SELECT_SCOPE);
                                roleAuthFieldVo.setControlScope(CONFIG_CONTROL_SCOPE);
                            }
                        }
                        if ("dictionaryAuth".equals(itemType)) {
                            //[{"childCode":"WAIT,SUSPEND","code":"JE_AUDFLAG"}]
                            DictCanCelAuthScopeVo dictCanCelAuthScopeVo = new DictCanCelAuthScopeVo();
                            dictCanCelAuthScopeVo.setId(dataId);
                            List<DictionaryVo> list = JSON.parseArray(configInfo, DictionaryVo.class);
                            dictCanCelAuthScopeVo.setDictList(list);
                            if ("org".equals(dataType)) {
                                orgDict.add(dictCanCelAuthScopeVo);
                            }
                            if ("dept".equals(dataType)) {
                                deptDict.add(dictCanCelAuthScopeVo);
                            }
                            if ("role".equals(dataType)) {
                                roleDict.add(dictCanCelAuthScopeVo);
                            }
                        }
                        if ("roleSqlAuth".equals(itemType)) {
                            RoleSqlAuthScopeVo roleSqlAuthScopeVo = new RoleSqlAuthScopeVo();
                            roleSqlAuthScopeVo.setId(dataId);
                            JSONObject jsonObject = JSON.parseObject(configInfo);
                            roleSqlAuthScopeVo.setSql(jsonObject.getString("sql"));
                            roleSqlAuthScopeVo.setCoverSql(jsonObject.getString("coverSql"));
                            if ("org".equals(dataType)) {
                                orgRoleSql.add(roleSqlAuthScopeVo);
                            }
                            if ("dept".equals(dataType)) {
                                deptRoleSql.add(roleSqlAuthScopeVo);
                            }
                            if ("role".equals(dataType)) {
                                roleRoleSql.add(roleSqlAuthScopeVo);
                            }
                        }
                    }
                    if ("dictionaryAuth".equals(itemType)) {
                        authItem.set("FUNCPERM_CONFIG", JSON.toJSONString(dictionaryAuthVo));
                    }
                    if ("roleSqlAuth".equals(itemType)) {
                        authItem.set("FUNCPERM_CONFIG", JSON.toJSONString(roleSqlAuthVo));
                    }
                    if ("fieldAuth".equals(itemType)) {
                        authItem.set("FUNCPERM_CONFIG", JSON.toJSONString(fieldAuthVo));
                    }
                }
                buildRetureData(itemType, authItem, dynaBean);
                if (Strings.isNullOrEmpty(authItem.getStr("FUNCPERM_COVER_VALUE"))) {
                    authItem.setStr("FUNCPERM_COVER_VALUE", "and");
                }
            }
        } else {
            List<DynaBean> list = metaService.select("JE_CORE_FUNCPERM", ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_ID",
                    dynaBean.getStr("FUNCPERM_FUNCINFO_ID")));
            String coverValue = "and";
            if (list.size() > 0) {
                if (!Strings.isNullOrEmpty(list.get(0).getStr("FUNCPERM_COVER_VALUE"))) {
                    coverValue = list.get(0).getStr("FUNCPERM_COVER_VALUE");
                }
            }
            DynaBean authItem = new DynaBean();
            buildRetureData(FUNCPERM_TYPE, authItem, dynaBean);
            authItem.setStr("FUNCPERM_COVER_VALUE", coverValue);
            authList.add(authItem);
        }
        return authList;
    }

    private void buildRetureData(String itemType, DynaBean authItem, DynaBean parm) {
        JSONTreeNode roleTree = roleRpcService.buildRoleTreeByRoleIds(null, false);
        if ("fieldAuth".equals(itemType)) {
            //装配角色树信息
            authItem.set("roleTree", roleTree);
            //装配字段信息
            List<Map<String, Object>> columnList = metaService.selectSql("SELECT RESOURCEFIELD_CODE,RESOURCEFIELD_NAME,JE_CORE_RESOURCEFIELD_ID FROM JE_CORE_RESOURCEFIELD WHERE RESOURCEFIELD_XTYPE NOT IN ('fieldset','child','displayfield','childfuncfield') AND RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_HIDDEN='0' ORDER BY SY_ORDERINDEX ASC", parm.getStr("FUNCPERM_FUNCINFO_ID"));
            authItem.set("columnList", columnList);
        }
        if ("dictionaryAuth".equals(itemType)) {
            //装配角色树信息
            authItem.set("roleTree", roleTree);
            //装配字典信息
            List<Map<String, Object>> dictList = getFuncFieldDic(parm.getStr("FUNCPERM_FUNCINFO_ID"), (Boolean) parm.get("en"));
            authItem.set("dictList", dictList);
        }
        if ("roleSqlAuth".equals(itemType)) {
            //装配角色树信息
            authItem.set("roleTree", roleTree);
        }
    }


    @Override
    public List<Map<String, Object>> getFuncFieldDic(String funcId, Boolean en) {

        List<DynaBean> fields = metaService.select("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder()
                .eq("RESOURCEFIELD_FUNCINFO_ID", funcId)
                .in("RESOURCEFIELD_XTYPE", "rgroup", "cgroup", "cbbfield", "treessfield", "treessareafield", "barfield")
                .selectColumns("JE_CORE_RESOURCEFIELD_ID,RESOURCEFIELD_CONFIGINFO"));
        List<String> ddCodes = new ArrayList<String>();
        for (DynaBean field : fields) {
            String configInfo = field.getStr("RESOURCEFIELD_CONFIGINFO", "");
            if (StringUtil.isNotEmpty(configInfo)) {
                String ddCode = configInfo.split(",")[0];
                if (StringUtil.isNotEmpty(ddCode) && !ddCodes.contains(ddCode)) {
                    ddCodes.add(ddCode);
                }
            }
        }
        List<Map<String, Object>> list = new ArrayList<>();
        for (String code : ddCodes) {
            DynaBean dynaBean = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder()
                    .eq("DICTIONARY_DDCODE", code).apply("and (SY_STATUS = '' or SY_STATUS = '1' or SY_STATUS is NULL)")
                    .selectColumns("JE_CORE_DICTIONARY_ID,DICTIONARY_DDCODE,DICTIONARY_DDNAME"));

            List<DictionaryItemVo> items = null;
            if (dynaBean != null) {
                items = dictionaryRpcService.buildChildrenList(dynaBean, en, new Query(), "");
                Map<String, Object> map = new HashMap<>();
                map.put("code", dynaBean.getStr("DICTIONARY_DDCODE"));
                map.put("text", dynaBean.getStr("DICTIONARY_DDNAME"));
                map.put("item", items);
                list.add(map);
            }
        }
        return list;
    }

    @Override
    public void restoreDefault(String funcCode) {
        metaService.delete("JE_CORE_FUNCPERM", ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_CODE", funcCode));
        //清除缓存
        metaFuncPermService.restoreDefault(funcCode);
    }

    @Override
    public Map<String, Object> getFuncConfigInfo(String funcCode) {
        Map<String, Object> redisMap = new HashMap<>();
        /**
         *  字段,以后加上租户
         *  选择控制、控制范围，都是or的关系
         */
        Map<String, Object> fieldMap = getDataPermFieldConfig(funcCode);
        redisMap.put("field", fieldMap);

        /**
         * 字典
         */
        Map<String, Object> map = getDataPermDictConfig(funcCode);
        redisMap.put("dict", map);
        String currentTenantId = SecurityUserHolder.getCurrentAccountTenantId();
        if (Strings.isNullOrEmpty(currentTenantId)) {
            funcPermCache.putCache(funcCode, redisMap);
        } else {
            funcPermCache.putCache(currentTenantId, funcCode, redisMap);
        }

        return redisMap;
    }

    @Override
    public JSONTreeNode getTree(BaseMethodArgument param, HttpServletRequest request) {
        List<DynaBean> productList = metaService.select("JE_PRODUCT_MANAGE", ConditionsWrapper.builder().eq("SY_STATUS", "1").orderByAsc("PRODUCT_TYPE", "SY_ORDERINDEX"));
        JSONTreeNode productRootNode = buildProductTree(productList);
        JSONTreeNode template = beanService.getTreeTemplate("JE_CORE_FUNCINFO");
        for (JSONTreeNode product : productRootNode.getChildren()) {
            List<Map<String, Object>> funcList = metaService.selectSql(
                    "SELECT SY_PRODUCT_CODE,SY_PRODUCT_NAME,SY_ORDERINDEX,JE_CORE_FUNCINFO_ID,SY_PARENT,SY_NODETYPE,FUNCINFO_NODEINFOTYPE,FUNCINFO_FUNCNAME,FUNCINFO_FUNCCODE,SY_LAYER,FUNCINFO_TABLENAME,SY_PATH,SY_TREEORDERINDEX,SY_PRODUCT_ID FROM JE_CORE_FUNCINFO WHERE SY_PRODUCT_ID='" + product.getId() + "'");
            List<JSONTreeNode> jsonTreeNodeList = commonService.buildJsonTreeNodeList(template, funcList, null, null, false);
            JSONTreeNode childJSONTreeNode = commonService.buildJSONNewTree(jsonTreeNodeList, "ROOT");
            product.setChildren(childJSONTreeNode.getChildren());
        }
        return productRootNode;
    }

    private JSONTreeNode buildProductTree(List<DynaBean> productList) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        for (DynaBean product : productList) {
            JSONTreeNode node = buildProductTreeNode(rootNode.getId(), product);
            if (node != null) {
                rootNode.getChildren().add(node);
            }
        }
        return rootNode;
    }


    private JSONTreeNode buildProductTreeNode(String id, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.getPkValue());
        node.setParent(id);
        node.setLeaf(true);
        node.setText(bean.getStr("PRODUCT_NAME"));
        node.setCode(bean.getStr("PRODUCT_CODE"));
        node.setIcon(bean.getStr("PRODUCT_ICON"));
        node.setOrderIndex(bean.getStr("SY_ORDERINDEX"));
        node.setNodeInfo(bean.getStr("PRODUCT_CODE"));
        node.setNodeType("GENERAL");
        node.setNodePath(bean.getPkValue());
        node.setDisabled("");
        node.setDescription(bean.getStr("PRODUCT_DESCRIBE"));
        node.setNodeInfoType("product");
        //node.setBean(bean.getValues());
        return node;
    }

    private Map<String, Object> getDataPermFieldConfig(String funcCode) {
        FieldAuthVo fieldAuthVo = metaFuncPermService.getFiledAuth(funcCode);
        Map<String, Object> resultCode = new HashMap<>();
        if (fieldAuthVo == null) {
            return resultCode;
        }
        DynaBean dynaBean = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode));
        List<Map<String, Object>> columnList = metaService.selectSql("SELECT JE_CORE_RESOURCEFIELD_ID,RESOURCEFIELD_CODE FROM JE_CORE_RESOURCEFIELD WHERE RESOURCEFIELD_XTYPE NOT IN ('fieldset','child','displayfield','childfuncfield') AND RESOURCEFIELD_FUNCINFO_ID={0} AND RESOURCEFIELD_HIDDEN='0' ORDER BY SY_ORDERINDEX ASC", dynaBean.getStr("JE_CORE_FUNCINFO_ID"));
        Set<String> editFields = new HashSet<>();
        Set<String> showFields = new HashSet<>();
        //部门
        FieldAuthScopeVo deptAuthFieldVo = fieldAuthVo.getDeptAuthFieldVo();
        if (deptAuthFieldVo != null && deptAuthFieldVo.getDatas() != null) {
            String deptControlScope = deptAuthFieldVo.getControlScope();
            String deptSelectControl = deptAuthFieldVo.getSelectControl();
            List<FieldAuthDataVo> deptFieldAuthDataVoList = deptAuthFieldVo.getDatas();
            //当前账号所属部门
            String accountDepartmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
            if (deptFieldAuthDataVoList.size() > 0) {
                for (FieldAuthDataVo fieldAuthDataVo : deptFieldAuthDataVoList) {
                    if (fieldAuthDataVo.getId().equals(accountDepartmentId)) {
                        bulidFieldList(deptControlScope, deptSelectControl, fieldAuthDataVo, editFields, showFields);
                    }
                }
            }

        }
        //角色
        FieldAuthScopeVo roleAuthFieldVo = fieldAuthVo.getRoleAuthFieldVo();
        String roleControlScope = roleAuthFieldVo.getControlScope();
        String roleSelectControl = roleAuthFieldVo.getSelectControl();
        if (roleAuthFieldVo != null && roleAuthFieldVo.getDatas() != null) {
            //当前账号所属角色ids
            List<String> roleIds = SecurityUserHolder.getCurrentAccount().getRoleIds();
            List<FieldAuthDataVo> roleFieldAuthDataVoList = roleAuthFieldVo.getDatas();
            if (roleFieldAuthDataVoList.size() > 0) {
                for (FieldAuthDataVo fieldAuthDataVo : roleFieldAuthDataVoList) {
                    if (roleIds.contains(fieldAuthDataVo.getId())) {
                        bulidFieldList(roleControlScope, roleSelectControl, fieldAuthDataVo, editFields, showFields);
                    }
                }
            }
        }
        //机构
        FieldAuthScopeVo orgAuthFieldVo = fieldAuthVo.getOrgAuthFieldVo();
        String orgControlScope = orgAuthFieldVo.getControlScope();
        String orgSelectControl = orgAuthFieldVo.getSelectControl();
        if (orgAuthFieldVo != null && orgAuthFieldVo.getDatas() != null) {
            List<FieldAuthDataVo> orgFieldAuthDataVoList = orgAuthFieldVo.getDatas();
            //当前账号所属机构
            String accountRealOrgId = SecurityUserHolder.getCurrentAccountRealOrgId();
            if (orgFieldAuthDataVoList.size() > 0) {
                for (FieldAuthDataVo fieldAuthDataVo : orgFieldAuthDataVoList) {
                    if (fieldAuthDataVo.getId().equals(accountRealOrgId)) {
                        bulidFieldList(orgControlScope, orgSelectControl, fieldAuthDataVo, editFields, showFields);
                    }
                }
            }
        }
        Map<String, Object> resultId = new HashMap<>();
        if (showFields.size() > 0) {
            for (String str : showFields) {
                resultId.put(str, "show");
            }
        }
        if (editFields.size() > 0) {
            for (String str : editFields) {
                resultId.put(str, "edit");
            }
        }
        for (Map<String, Object> map : columnList) {
            String fieldId = map.get("JE_CORE_RESOURCEFIELD_ID").toString();
            String fieldCode = map.get("RESOURCEFIELD_CODE").toString();
            if (resultId.containsKey(fieldId)) {
                resultCode.put(fieldCode, resultId.get(fieldId));
            }
        }

        return resultCode;
    }

    /**
     * @param controlScope：   0：查询；1：修改
     * @param selectControl   :0:启用；1：禁用
     * @param fieldAuthDataVo
     * @param editFields
     * @param showFields
     */
    private void bulidFieldList(String controlScope, String selectControl, FieldAuthDataVo fieldAuthDataVo, Set<String> editFields, Set<String> showFields) {
        if (fieldAuthDataVo.getAllFields() != null && fieldAuthDataVo.getAllFields().size() > 0) {
            for (FieldStateVo fieldStateVo : fieldAuthDataVo.getAllFields()) {
                String code = fieldStateVo.getCode();
                //1:勾选；0不勾选
                String value = fieldStateVo.getValue();
                if ("0".equals(selectControl)) {
                    if ("1".equals(value)) {
                        if ("0".equals(controlScope)) {
                            showFields.add(code);
                        }
                        if ("1".equals(controlScope)) {
                            editFields.add(code);
                        }
                    }
                }
                if ("1".equals(selectControl)) {
                    if ("0".equals(value)) {
                        if ("0".equals(controlScope)) {
                            showFields.add(code);
                        }
                        if ("1".equals(controlScope)) {
                            editFields.add(code);
                        }
                    }
                }
            }
        }
    }

    private Map<String, Object> getDataPermDictConfig(String funcCode) {
        DictionaryAuthVo dictionaryAuth = metaFuncPermService.getDictionaryAuth(funcCode);
        List<DictionaryVo> resultList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        if (dictionaryAuth != null) {
            List<DictCanCelAuthScopeVo> roleList = dictionaryAuth.getDictCanCelAuthRoleList();
            List<String> roleIds = SecurityUserHolder.getCurrentAccount().getRoleIds();
            if ((roleList != null && roleList.size() > 0) && (roleIds != null && roleIds.size() > 0)) {
                for (DictCanCelAuthScopeVo item : roleList) {
                    if (roleIds.contains(item.getId())) {
                        resultList.addAll(item.getDictList());
                    }
                }
            }
            String accountDepartmentId = SecurityUserHolder.getCurrentAccountDepartment().getId();
            List<DictCanCelAuthScopeVo> deptList = dictionaryAuth.getDictCanCelAuthDeptList();
            if (deptList != null && deptList.size() > 0 && StringUtil.isNotEmpty(accountDepartmentId)) {
                for (DictCanCelAuthScopeVo item : deptList) {
                    if (accountDepartmentId.equals(item.getId())) {
                        resultList.addAll(item.getDictList());
                    }
                }
            }
            List<DictCanCelAuthScopeVo> orgList = dictionaryAuth.getDictCanCelAuthOrgList();
            String accountRealOrgId = SecurityUserHolder.getCurrentAccountRealOrgId();
            for (DictCanCelAuthScopeVo item : orgList) {
                if (accountRealOrgId.equals(item.getId())) {
                    resultList.addAll(item.getDictList());
                }
            }
            if (resultList.size() > 0) {
                for (DictionaryVo item : resultList) {
                    if (map.containsKey(item.getCode())) {
                        map.put(item.getCode(), removeDuplicate(map.get(item.getCode()) + "," + item.getChildCode()));
                    } else {
                        map.put(item.getCode(), item.getChildCode());
                    }
                }
            }
        }
        return map;
    }

    public List<String> removeDuplicate(String str) {
        if (StringUtil.isNotEmpty(str)) {
            List<String> list = Arrays.asList(str.split(","));
            return list.stream().distinct().collect(Collectors.toList());
        }
        return null;
    }

}
